from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List, Optional
import logging
from datetime import datetime, date

from backend.database.session import get_db
from backend.database import crud
from backend.services import data_fetcher
from backend.schemas.schema import APIResponse, StockZTBase

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建路由实例
router = APIRouter(prefix="/api", tags=["K线数据"])


@router.post("/save_all_daily_kline", response_model=APIResponse[str])
async def save_all_daily_kline(
    start_date: str = Query(..., description="开始日期，格式为 YYYYMMDD"),
    end_date: str = Query(..., description="结束日期，格式为 YYYYMMDD"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取全量A股的日K线数据并保存到数据库
    
    Args:
        start_date: 开始日期，格式为 YYYYMMDD
        end_date: 结束日期，格式为 YYYYMMDD
    """
    try:
        # 获取全量A股列表
        stock_list = await data_fetcher.fetch_stock_list()
        
        if not stock_list:
            return APIResponse[str](
                success=True,
                data=[],
                count=0,
                message="未获取到股票列表"
            )
        
        total_saved = 0
        success_count = 0
        
        # 遍历每只股票获取K线数据并保存
        for stock in stock_list:
            code = stock['code']
            try:
                # 获取该股票的日K线数据
                kline_data = await data_fetcher.fetch_daily_kline_data(code, start_date, end_date)
                
                if kline_data:
                    # 保存到数据库
                    created_count = await crud.batch_create_stock_daily_kline(db, code, kline_data)
                    total_saved += created_count
                    success_count += 1
                    
                logger.info(f"已处理股票 {code} 的日K线数据")
            except Exception as e:
                logger.error(f"处理股票 {code} 的日K线数据时发生错误: {str(e)}")
                continue
        
        return APIResponse[str](
            success=True,
            data=[f"共处理 {len(stock_list)} 只股票"],
            count=total_saved,
            message=f"成功保存 {success_count} 只股票共 {total_saved} 条日K线数据"
        )
    except Exception as e:
        logger.error(f"批量保存A股日K线数据时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"保存数据时发生错误: {str(e)}")


@router.post("/save_all_minute_kline", response_model=APIResponse[str])
async def save_all_minute_kline(
    period: str = Query("1", description="时间周期，可选 1, 5, 15, 30, 60 分钟"),
    start_date: Optional[str] = Query(None, description="开始日期，格式为 YYYYMMDD"),
    end_date: Optional[str] = Query(None, description="结束日期，格式为 YYYYMMDD"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取全量A股的分钟K线数据并保存到数据库
    
    Args:
        period: 时间周期，可选 "1", "5", "15", "30", "60" 分钟
        start_date: 开始日期，格式为 YYYYMMDD
        end_date: 结束日期，格式为 YYYYMMDD
    """
    try:
        # 获取全量A股列表
        stock_list = await data_fetcher.fetch_stock_list()
        
        if not stock_list:
            return APIResponse[str](
                success=True,
                data=[],
                count=0,
                message="未获取到股票列表"
            )
        
        total_saved = 0
        success_count = 0
        
        # 遍历每只股票获取K线数据并保存
        for stock in stock_list:
            code = stock['code']
            try:
                # 获取该股票的分钟K线数据
                kline_data = await data_fetcher.fetch_minute_kline_data(code, period, start_date, end_date)
                
                if kline_data:
                    # 保存到数据库
                    created_count = await crud.batch_create_stock_minute_kline(db, code, kline_data)
                    total_saved += created_count
                    success_count += 1
                    
                logger.info(f"已处理股票 {code} 的{period}分钟K线数据")
            except Exception as e:
                logger.error(f"处理股票 {code} 的{period}分钟K线数据时发生错误: {str(e)}")
                continue
        
        return APIResponse[str](
            success=True,
            data=[f"共处理 {len(stock_list)} 只股票"],
            count=total_saved,
            message=f"成功保存 {success_count} 只股票共 {total_saved} 条{period}分钟K线数据"
        )
    except Exception as e:
        logger.error(f"批量保存A股{period}分钟K线数据时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"保存数据时发生错误: {str(e)}")


@router.post("/save_daily_kline", response_model=APIResponse[str])
async def save_daily_kline(
    code: str = Query(..., description="股票代码"),
    start_date: str = Query(..., description="开始日期，格式为 YYYYMMDD"),
    end_date: str = Query(..., description="结束日期，格式为 YYYYMMDD"),
    db: AsyncSession = Depends(get_db)
):
    """
    从akshare获取股票日K线数据并保存到数据库
    
    Args:
        code: 股票代码
        start_date: 开始日期，格式为 YYYYMMDD
        end_date: 结束日期，格式为 YYYYMMDD
    """
    try:
        # 从akshare获取数据
        kline_data = await data_fetcher.fetch_daily_kline_data(code, start_date, end_date)
        
        if not kline_data:
            return APIResponse[str](
                success=True,
                data=[],
                count=0,
                message="未获取到数据"
            )
        
        # 保存到数据库
        created_count = await crud.batch_create_stock_daily_kline(db, code, kline_data)
        
        return APIResponse[str](
            success=True,
            data=[f"股票 {code} 的日K线数据"],
            count=created_count,
            message=f"成功保存 {created_count} 条日K线数据"
        )
    except Exception as e:
        logger.error(f"保存股票 {code} 日K线数据时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"保存数据时发生错误: {str(e)}")


@router.post("/save_minute_kline", response_model=APIResponse[str])
async def save_minute_kline(
    code: str = Query(..., description="股票代码"),
    period: str = Query("1", description="时间周期，可选 1, 5, 15, 30, 60 分钟"),
    start_date: Optional[str] = Query(None, description="开始日期，格式为 YYYYMMDD"),
    end_date: Optional[str] = Query(None, description="结束日期，格式为 YYYYMMDD"),
    db: AsyncSession = Depends(get_db)
):
    """
    从akshare获取股票分钟K线数据并保存到数据库
    
    Args:
        code: 股票代码
        period: 时间周期，可选 "1", "5", "15", "30", "60" 分钟
        start_date: 开始日期，格式为 YYYYMMDD
        end_date: 结束日期，格式为 YYYYMMDD
    """
    try:
        # 从akshare获取数据
        kline_data = await data_fetcher.fetch_minute_kline_data(code, period, start_date, end_date)
        
        if not kline_data:
            return APIResponse[str](
                success=True,
                data=[],
                count=0,
                message="未获取到数据"
            )
        
        # 保存到数据库
        created_count = await crud.batch_create_stock_minute_kline(db, code, kline_data)
        
        return APIResponse[str](
            success=True,
            data=[f"股票 {code} 的{period}分钟K线数据"],
            count=created_count,
            message=f"成功保存 {created_count} 条{period}分钟K线数据"
        )
    except Exception as e:
        logger.error(f"保存股票 {code} {period}分钟K线数据时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"保存数据时发生错误: {str(e)}")